特殊数字

  1. 如果两个数a和b,a的所有真因数之和等于b,b的所有真因数之和等于a,则称a,b是一对亲和数。求50000以内的所有亲和数,真因数不包括本身。
  2. 只有1和本身作为因子的数称作素数。求1000以内的所有素数,习惯上1不作为素数。
  3. 我们把只包含因子2、3和5的数称为丑数。求按从小到大的顺序排列的第1500个丑数。习惯上我们把1当做第一个丑数。

1、思路:

  常规方法:对每个数i(从1到N)进行处理,处理的方法是用j(从1到i/2)进行取余,看是否为0。能整除的话,sum[i] += j。

  伴随数组:从因子2开始处理,对于下标是2的倍数说明因子含有2;接下去处理因子3,对于下标是3的倍数说明因子含有3;依次类推。

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 const int N = 50000;
 6 
 7 int main()
 8 {
 9     int i, j, sum[N + 1];
10     for (i = 1; i <= N; i++)
11         sum[i] = 1; //1是所有数的真因数所以全部置1
12     for (i = 2; i <= N >> 1; i++)
13     {
14         j = i << 1; //从2倍开始加,因为是真因数,不包含本身
15         while (j <= N)
16         {
17             sum[j] += i;
18             j += i; //往3倍、4倍...n倍上加
19         }
20     }
21     for (i = 200; i <= N; i++)
22     {
23         if (sum[i] > i && sum[i] <= N && sum[sum[i]] == i)
24             cout << i << " " << sum[i] << endl;
25     }
26     return 0;
27 }

 

2、思路:

  常规方法:对每个数i(从2到N)进行判断是否是素数,判断的规则是用j(从2到sqrt(i))进行取余,看是否为0。能整除的话说明不是素数。

  伴随数组:筛选法,维护prime的bool数组,当下标为2、3、4...的倍数时,标记为false。

 1 #include <stdio.h>
 2 #include <math.h>
 3 
 4 #define N 100
 5 
 6 int main()
 7 {
 8     int i, j;
 9     bool prime[N + 1];
10     for (i = 1; i <= N; i++)
11         prime[i] = true;
12     prime[1] = false;
13     for (i = 2; i <= sqrt((double)N); i++)
14     {
15         if (prime[i])
16         {
17             j = i << 1;
18             while (j <= N)
19             {
20                 prime[j] = false;
21                 j += i;
22             }
23         }
24     }
25     for (int i = 1; i <= N; i++)
26         if (prime[i]) printf("%d ", i);
27     return 0;
28 }

 

posted on 2013-04-16 21:05  月moon鸟  阅读(250)  评论(0编辑  收藏  举报

导航